package com.example.slidecaptcha2;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.*;


import java.io.File;
import java.io.InputStream;
import java.io.Serializable;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;

/**
 * 滑块验证码、短信验证码
 *
 * @author yyf900524
 * @date 2019/08/21
 */
@BaseResponse
@RestController
@RequestMapping("/verifyCode")
public class VerifyCodeController {

    private static final Logger LOGGER = LoggerFactory.getLogger(VerifyCodeController.class);

    @Autowired
    BasicConfig basicConfig;

    @Autowired
    RedisUtil redisUtil;

    /**
     * 获取滑块验证码
     *
     * @param imgVerifyVo
     * @return
     */
//    @ApiOperation("获取滑块验证码")
    @RequestMapping(value = "/getImageVerifyCode", method = RequestMethod.POST)
    public ResponseResult getImgVerifyCode(@RequestBody ImgVerifyVo imgVerifyVo) {
        if (StringUtils.isBlank(imgVerifyVo.getFlowId())) {
            return new ResponseResult(ResponseCode.SERVICE_ERROR.getCode(), "[flowId]不能为空", null);
        }

        //生成图片返回
        Map<String, Object> pictureMap = null;
        Map<String, Object> returnMap = null;
        SecureRandom imageNoRandom = new SecureRandom();
        int imageNo = imageNoRandom.nextInt(basicConfig.getImageCount());
        pictureMap = (Map<String, Object>) redisUtil.getObject("imageVerify:" + imageNo);
        if (pictureMap == null) {
            File templateFile;  //模板图片
            File targetFile;  //
            int count = 0;
            while (pictureMap == null) {
                SecureRandom random = new SecureRandom();
                int templateNo = random.nextInt(1) + 1;
                int targetNo = random.nextInt(15) + 1;
                try {
                    InputStream stream = null;
                    templateFile = new File(templateNo + ".png");
                    if (!templateFile.exists()) {
                        stream = ClassUtils.getDefaultClassLoader().getResourceAsStream("static/templates/" + templateNo + ".png");
                        FileUtils.copyInputStreamToFile(stream, templateFile);
                    }
                    targetFile = new File(targetNo + ".jpg");
                    if (!targetFile.exists()) {
                        stream = ClassUtils.getDefaultClassLoader().getResourceAsStream("static/targets/" + targetNo + ".jpg");
                        FileUtils.copyInputStreamToFile(stream, targetFile);
                    }
                    pictureMap = VerifyCodeFactory.getInstance(templateFile, targetFile);
                } catch (Exception e) {
                    count += 1;
                    if (count >= 5) {
                        LOGGER.error("获取图形验证码服务-生成图片流发生异常 => {}", e.getMessage());
                        return new ResponseResult(2, "生成图片流发生异常：" + e, null);
                    }
                }
            }
        }
        //清空xy坐标
        HashMap<String, Integer> xyPoint = (HashMap) pictureMap.get("xyPoint");
        xyPoint.put("tryCount", 0);
        redisUtil.setObject("flowId" + imgVerifyVo.getFlowId(), (Serializable) xyPoint, 300);
        pictureMap.put("yPoint", xyPoint.get("y"));
        returnMap = new HashMap<>();
        returnMap.putAll(pictureMap);
        returnMap.remove("xyPoint");
        return new ResponseResult(ResponseCode.SUCCESS.getCode(), "请求成功", pictureMap);
    }

    /**
     * 验证滑块验证码
     *
     * @param imgVerifyVo
     * @return
     */
//    @ApiOperation("验证滑块验证码")
    @RequestMapping(value = "/checkImgVerifyCode", method = RequestMethod.POST)
    public ResponseResult checkImgVerifyCode(@RequestBody ImgVerifyVo imgVerifyVo) {
        if (StringUtils.isBlank(imgVerifyVo.getFlowId())) {
            return new ResponseResult(ResponseCode.RESOURCES_NOT_EXIST.getCode(), "[flowId]不能为空", null);
        }
        if (StringUtils.isBlank(imgVerifyVo.getxPoint())) {
            return new ResponseResult(ResponseCode.RESOURCES_NOT_EXIST.getCode(), "[xPoint]不能为空", null);
        }
        //获取存储对象
        Map<String, Integer> pointMap = (Map<String, Integer>) redisUtil.getObject("flowId" + imgVerifyVo.getFlowId());
        if (null == pointMap) {
            return new ResponseResult(ResponseCode.RESOURCES_NOT_EXIST.getCode(), "无效的请求，该flowId未生成验证", null);
        }
        int pointX = pointMap.get("x");
        int pointY = pointMap.get("y");
        //判断X与允许偏差值的差距
        int x = pointX - Integer.parseInt(imgVerifyVo.getxPoint());
        if (x > 5 || x < -5) {
            return new ResponseResult(ResponseCode.RESOURCES_NOT_EXIST.getCode(), "未通过验证", null);
        }
        return new ResponseResult(ResponseCode.SUCCESS.getCode(), "验证通过", null);
    }
}
